//#include "IAP.h"
//#include "globalDef.h"
//#include "crc32.h"
//#include "string.h"
//#include "Flash_user.h"
//#include "SPI_Flash.h"
//#include "algorithm.h"
//#include "L610.h"
//#include "peripheral.h"
//#include "uart_hw.h"
//#include "debug_prt.h"

//Up_TypeDef		tagUp;


///*
//初始化IAP变量
//*/
//void initIAP (void)
//{
//	memset(&tagUp,0,sizeof(tagUp));
//	
//}


///*
//该函数需要一直被主循环调用，用于管理IAP
//*/
//void IAPProcess (void)
//{
//	
//	//开机检查升级Flash区域是否为空, 擦除相关Flash
//	//并上报升级成功失败
//	selfCheckUpAdr();
//	

//	//检查是否升级固件完整性并启动重启升级
//	checkIapValidAndReboot();
//	

//}



////检查是否升级固件完整性并启动重启升级
//void checkIapValidAndReboot(void)
//{
//	uint32_t temp;
//	
//	if (tagUp.chk_flash_sta == 0x03)
//	{
//		//后面建议增加计算校验的检查
//		switch(tagUp.calcCrcSta)
//		{
//			case 0x00:
//				tagUp.calcCrcSta++;
//			
//				#if _EnIapDebug_def	
//				printf("start calc crc, %s at line %d\r\n", __FILE__,__LINE__);
//				#endif
//				break;
//			
//			case 0x01:
//				if (crc32_chk(&temp) == 0x01)
//				{
//					//校验成功
//					tagUp.calcCrcSta++;
//					#if _EnIapDebug_def	
//					printf("FW Crc OK, %s at line %d\r\n",
//								 __FILE__,__LINE__);
//					#endif
//				}
//				else
//				{
//					//校验失败
//					tagUp.chk_flash_sta = 0x04;
//					#if _EnIapDebug_def	
//					printf("FW Crc Err , %s at line %d\r\n",
//								 __FILE__,__LINE__);
//					#endif
//				}
//				
//				break;
//			
//			case 0x02:
//				tagUp.calcCrcSta++;
//				break;
//			
//			case 0x03:
//				tagUp.calcCrcSta++;
//				break;
//			
//			case 0x04:
//				tagUp.calcCrcSta++;
//				break;
//			
//			case 0x05:
//				//重启到IAP，等待升级
//				reBootMe();
//				break;
//		}
//		
//	}
//	else
//	{
//		tagUp.calcCrcSta = 0;
//	}
//}




///*
//本意Flash顺序存储，
//现在这样写，flash可以乱序存储升级包
//返回0失败，
//返回1成功
//*/
//uint8_t find_pac_cur_adr(uint16_t pac_cur, uint32_t * adr)
//{
//	uint8_t da[1024];
//	uint32_t adrTmp, endAdr;
//	uint16_t cur;
//	uint8_t errCnt = 0;
//	uint16_t xor_len;
//	uint16_t pac_len;
//	

//	adrTmp = StAddrOf_Up;
//	endAdr = (uint32_t)EndAddrOf_Up;


//	while (adrTmp < endAdr)
//	{
////		deal_obd_addragain:		
//		Flash_Read_Data(adrTmp, da, 1);
//		if (da[0] == 0xFA)
//		{
//			//需要检验校验，这个是后来添加上的，稍感不是那么完美
//			Flash_Read_Data(adrTmp+16, da, 2);
//			cur = (da[0] << 8) | da[1];
//			
//			if (cur == pac_cur)
//			{
//	
//				Flash_Read_Data(adrTmp, da, 1024);

//				pac_len = (da[12] << 8) | da[13];
//				xor_len = pac_len + 19;
//				
//				if (get_chk_xor(da, xor_len) == 0)
//				{
//					*adr = adrTmp;
//					return 1;
//				}
//				else
//				{
//					errCnt ++;
//					if (errCnt > 10)
//					{
//						return 0;
//					}
//				}
//			}
//			else if ( cur == 0xff )
//			{
//				errCnt ++;
//				if (errCnt > 10)
//				{
//					return 0;
//				}
//			}
//		}
//		else
//		{
//			errCnt ++;
//			if (errCnt > 10)
//			{
//				return 0;
//			}
//		}

//		adrTmp += 1024;
//	}

//	return 0;
//}

///*
//返回0失败，
//返回1成功
//*/
//uint8_t crc32_chk(uint32_t * reLen)
//{
//	uint32_t crc = 0xffffffff;
//	uint32_t adr_cur;
//	uint16_t pac_all;
//	uint16_t pac_cur = 1;
//	uint8_t da[20];

//	uint8_t reData[1030];
//	uint16_t ulTmp;
//	*reLen = 0;
//	ulTmp = 0;

//	if (find_pac_cur_adr(pac_cur, &adr_cur) == 1)
//	{
//		
//		Flash_Read_Data(adr_cur, da, 20);	

//		pac_all = (da[14] << 8) | da[15];
//	}
//	else
//	{
//		return 0;
//	}
//	
//	while (pac_all >= pac_cur)
//	{
//		if (find_pac_cur_adr(pac_cur, &adr_cur) == 1)
//		{
//			if (get_pac_calc2(adr_cur, &crc, reData, &ulTmp) == 1)
//			{
//				*reLen = (*reLen) + ulTmp;
//				pac_cur ++;
//			}
//			else
//			{
//				return 0;
//			}
//		}
//		else
//		{
//			return 0;	//20160726 增加，发现还真有死在这里面的
//		}
//	}
//	
//	if ( crc == 0)
//	{
//		return 1;
//	}

//	return 0;
//}

///*
//返回0失败，
//返回1成功
//*/
//uint8_t get_pac_calc2(uint32_t adr, uint32_t * crc, uint8_t* pReData, uint16_t * pReLen)
//{


//	//uint8_t version[9];
//	uint16_t pac_len;

//	//uint16_t pac_cur;

//	uint16_t xor_len;
//	uint16_t i, j;
//	uint8_t da[1024];
//	uint8_t xor_decipher;

//	*pReLen = 0;

//	xor_decipher = key_xor;

//	Flash_Read_Data(adr, da, 1024);
//	
//	//type = da[1];
//	//ver_len = da[2];
//	pac_len = (da[12] << 8) | da[13];
//	//pac_all = (da[14] << 8) | da[15];
//	//pac_cur = (da[16] << 8) | da[17];


//	xor_len = pac_len + 19;
//	if (get_chk_xor(da, xor_len) == 0)
//	{
//		for (i = 0, j = 18; i < pac_len; i++)
//		{
//			da[i] = da[j++] ^ xor_decipher;
//			pReData[i] = da[i];
//		}
//		*pReLen = pac_len;

//		*crc = crc32(*crc, da, pac_len);
//		return 1;
//	}


//	return 0;
//}




///*
//检查是否都是0xff，如果是则返回0
//不全是FF返回1
//*/
//uint8_t chk_all_ff(uint8_t * pda, uint32_t len)
//{
//	uint32_t i;
//	for (i = 0; i < len;i++)
//	{
//		if (pda[i] != 0xff)
//		{
//			break;
//		}
//	}

//	if (i>=len)
//	{
//		return 0;
//	}

//	return 1;
//}

////开机检查升级Flash区域是否为空, 擦除相关Flash
//void selfCheckUpAdr(void)
//{
//	//开机只运行一次，检查存储区是否为空，非空则擦空
//	static uint8_t chkOnceSta = 0;
//	static uint32_t adrOfUp = 0;
//	uint8_t RdData[1024];
//	static uint32_t NeedReEraseOnce = 0;
//	
//	//一段小逻辑，每次升级失败要擦除1次存储区
//	if ((tagUp.chk_flash_sta == 0x04) &&	//曾经升级失败
//		(NeedReEraseOnce == 0x00))					//
//	{
//		NeedReEraseOnce = 0x01;
//		chkOnceSta = 0x00;
//		sendUpFirmwareSuccess(0, 1);
//	}
//	else if (tagUp.chk_flash_sta == 0x02)	//正在升级
//	{	//恢复可擦除标记
//		NeedReEraseOnce = 0x00;
//		//
//		chkOnceSta = 0x21;
//	}
//	
//	
//	//每调用1次擦除4k，防止占用CPU时间太长,开机会自动运行1次
//	switch(chkOnceSta)
//	{
//		case 0x00:
//			adrOfUp = StAddrOf_Up;
//			chkOnceSta ++;
//			break;
//		
//		case 0x01:
//			if (adrOfUp < EndAddrOf_Up)
//			{
//				Flash_Read_Data(adrOfUp, RdData, 1024);
//				if (chk_all_ff(RdData, 1024) == 0x00)
//				{
//					adrOfUp += 1024;
//				}
//				else
//				{
//					chkOnceSta= 0x03;
//					
//					//检查一下版本号，是否和当前相同，如果相同则上报升级成功
//					//如果第一块出现坏块，则不会上报正确结果，或者会误报内容
//					if ( (RdData[0] == 0xFA) &&
//							(RdData[1] == 0x00) &&
//							(RdData[2] == 0x09) &&
//							(memcmp(&RdData[3], _def_verson, 9) == 0)	)
//					{
//						sendUpFirmwareSuccess(0, 0);
//					}
//					else
//					{
//						//应该上报升级失败，但是如果Flash第一块有数据，就会误报内容，所以不报了
//					}
//				}
//			}
//			else
//			{
//				chkOnceSta = 0x20;
//			}
//			break;
//		
////		case 0x02:	//预留一步
////			break;
//		
//		case 0x03:
//			//开始逐块擦除
//			adrOfUp = StAddrOf_Up;
//			chkOnceSta ++;
//			#if _EnIapDebug_def	
//			printf("Falsh Check Need Erase, %s at line %d\r\n",__FILE__,__LINE__);
//			#endif
//			break;
//		
//		case 0x04:
//			if (adrOfUp < EndAddrOf_Up)
//			{
//				Flash_Erase(Sector_Erase,adrOfUp);
//				adrOfUp += 1024*4;
//			}
//			else
//			{
//				chkOnceSta = 0x20;
//			}
//			break;

//		case 0x20:	//此处说明都擦空了
//			chkOnceSta = 0x21;
//			tagUp.chk_flash_sta = 0x05;
//			#if _EnIapDebug_def	
//			printf("Falsh Check OK, %s at line %d\r\n",__FILE__,__LINE__);
//			#endif
//			break;
//		case 0x21:	//此处说明都擦空了
//			break;
//		
//	}
//}



///*
//计算异或校验
//*/
////uint8_t get_chk_xor(uint8_t * da, uint16_t len)
////{
////	uint8_t xorr;
////	uint16_t i;
////	xorr = 0;
////	for (i=0;i<len;i++)
////	{
////		xorr ^= da[i];
////	}

////	return xorr;
////}


///*
//说明：
//发固件数据给IAP

//输入参数：
//pDa缓存
//len送入缓存的字节数。
//详细说明len，因为底层做了坏块处理，每次写入建议800~950字节，
//最后一包不限大小。
//机制是上层程序写入的数据，按1024字节分块存储，即使写1字节，也会占用1024字节。

//*/
//uint32_t IapStoreData (uint16_t PacAll, uint16_t PacCur, uint8_t * pDa, uint32_t len)
//{
//	uint8_t ucDa[1024];
//	uint16_t idx;
//	uint8_t * pac_da;	//数据包开始
//	uint16_t pac_len;
//	uint16_t pac_all, pac_cur;
//	uint32_t adr;

//	
//	
//	if (len > MaxUpSizePerPack)
//	{
//		#if _EnIapDebug_def	
//		printf("%s pack too large at line %d\r\n",__FILE__,__LINE__);
//		#endif
//		tagUp.chk_flash_sta = 4;	//升级失败
//		return 4;
//	}
//	
//	if ( (PacCur == 0) ||
//		(PacCur > PacAll) )
//	{
//		tagUp.chk_flash_sta = 4;	//升级失败
//		return 5;
//	}
//	
//	if (PacCur == 1)	//收到第一包
//	{

//		tagUp.AllPacCnt = PacAll;
//		tagUp.CurPacCnt = 1;
//		tagUp.adr_last = StAddrOf_Up;	//第一包时确认存储地址
//		memcpy(tagUp.version, pDa+7, 9);
//		
//		
//		//擦空存储区
//		if (tagUp.chk_flash_sta != 0x05)
//		{
//			for(adr = StAddrOf_Up; adr < EndAddrOf_Up; adr+= 1024*4)
//			{
//				Flash_Erase(Sector_Erase,adr);
//			}
//		}
//		
//		tagUp.chk_flash_sta = 0;
//	}
//	
//	//如果后续下发包和第一包不同，返回失败
//	if (memcmp(tagUp.version, pDa+7, 9) != 0)
//	{
//		tagUp.chk_flash_sta = 4;
//		return 8;
//	}
//	
//	//如果升级类型不是0x00返回错误
//	if (pDa[0] != 0x00)
//	{
//		tagUp.chk_flash_sta = 4;
//		return 9;
//	}
//	
//	
//	
//	pac_da = pDa+20;	//有效数据
//	pac_len = len-20;	//后台下发的总文件长度，存储时使用的当前包长度
//	pac_all = PacAll;
//	pac_cur = PacCur;
//	
//	//要求只能顺序的一包包下发
//	if (tagUp.CurPacCnt != pac_cur)
//	{
//		return 0;
//	}
//		
//		
//	if ((tagUp.adr_last + 1204) > EndAddrOf_Up)
//	{
//		#if _EnIapDebug_def	
//		printf("%s Iap Size too large at line %d\r\n",__FILE__,__LINE__);
//		#endif
//		tagUp.chk_flash_sta = 4;	//升级失败
//		return 6;
//	}
//	
//	
//	if (tagUp.chk_flash_sta == 0x00)
//	{
//		//为了兼容之前存储格式，增加存储报文头
//		tagUp.chk_flash_sta = 0x02;
//	}
//	
//deal_reStore:	//重新存储多次

//	if (tagUp.chk_flash_sta == 0x02)
//	{
//		//组织好报文，
//		ucDa[0] = 0xFA;	//存储标记
//		ucDa[1] = 0x00;	//升级类型
//		ucDa[2] = 9;
//		
//		//
//		memcpy(&ucDa[3], tagUp.version, 9);
//		
//		//包长度
//		ucDa[12] = (uint8_t)(pac_len >> 8);
//		ucDa[13] = (uint8_t)(pac_len);
//		//总包数
//		ucDa[14] = (uint8_t)(pac_all >> 8);
//		ucDa[15] = (uint8_t)(pac_all);
//		//当前包号
//		ucDa[16] = (uint8_t)(pac_cur >> 8);
//		ucDa[17] = (uint8_t)(pac_cur);

//		memcpy(&ucDa[18], pac_da, pac_len);
//		idx = 18 + pac_len;
//		
//		//计算校验
//		ucDa[idx] = get_chk_xor(ucDa, idx);
//		idx ++;
//					
//		
//		//存入Flash
//		Flash_Write_Data(tagUp.adr_last, ucDa, idx);
//		//提取出重新计算校验
//		memset(ucDa, 0, 10);
//		Flash_Read_Data(tagUp.adr_last, ucDa, idx);
//		
//		if (get_chk_xor(ucDa, idx) == 0)
//		{
//			//下载包号增加，同时确认是否升级完成
//			if (tagUp.CurPacCnt >= tagUp.AllPacCnt)
//			{
//				//升级完成，待机重启即可
//				tagUp.chk_flash_sta = 3;
//			}
//			else
//			{
//				tagUp.adr_last += 1024;
//				tagUp.CurPacCnt++;
//			}
//		}
//		else
//		{
//			tagUp.errStoreCnt ++;
//			if (tagUp.errStoreCnt < 20)
//			{
//				tagUp.adr_last += 1024;
//				goto deal_reStore;
//			}
//			else
//			{
//				#if _EnIapDebug_def	
//				printf("Write Flash Error, %s at line %d\r\n",__FILE__,__LINE__);
//				#endif
//				//升级失败，无法写入
//				tagUp.chk_flash_sta = 4;
//				return 1;
//			}
//		}
//	}
//	else
//	{
//		#if _EnIapDebug_def	
//		printf("Ctrl Var Error = %d, %s at line %d\r\n",tagUp.chk_flash_sta, __FILE__,__LINE__);
//		#endif
//		return 7;
//	}	
//	
//	return 0;
//}


///*
//固件大小，单位字节

//说明：只能升级前调用1次，不能重复调用。因为调用后会初始化起始存储地址
//*/
////void tellMeFileSize(uint32_t size)
////{
////	tagUp.FileSize = size;
////	
////	//计算总包数
////	tagUp.CurPacCnt = 1;
////	tagUp.AllPacCnt = size / MaxUpSizePerPack;
////	if ((size % MaxUpSizePerPack) != 0)
////	{
////		tagUp.AllPacCnt++;
////	}
////	
////	tagUp.chk_flash_sta = 0;	//初始化控制变量
////	tagUp.errStoreCnt = 0;

////}


////参数0代表升级固件，0x0A升级IAP
//uint32_t sendUpFirmwareSuccess(uint8_t upType, u8 result)
//{
//	uint8_t txDa[5];
//	
//	txDa[0] = upType;
//	txDa[1] = result;
//		
//	return send_general_package_to_uart(0x2016, txDa, 2, 0, 0, 1);
//}






